package com.ruoyi.framework.interceptor;

import com.ruoyi.common.core.context.ContextUtil;
import com.ruoyi.common.utils.StringUtils;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.sql.Connection;
import java.util.Properties;

@Intercepts({ @Signature(method = "prepare", type = StatementHandler.class, args = { Connection.class}) })
public class DataScopeInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        String tenantCode= ContextUtil.getTenant();
        StatementHandler handler = (StatementHandler)invocation.getTarget();
        //由于mappedStatement中有我们需要的方法id,但却是protected的，所以要通过反射获取
        MetaObject statementHandler = SystemMetaObject.forObject(handler);
        MappedStatement mappedStatement = (MappedStatement) statementHandler.getValue("delegate.mappedStatement");
        //获取sql
        BoundSql boundSql = handler.getBoundSql();
        String sql = boundSql.getSql();
        //获取方法id
        String id = mappedStatement.getId();
        //获得方法类型 (如select,update)
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        if ("SELECT".equalsIgnoreCase(sqlCommandType.toString())) {
            //增强sql代码块  这里可通过判断用户权限为不通类型的用户拼接不同的sql
            if(StringUtils.isNotEmpty(tenantCode)){
                sql += " where tenant_code = '"+tenantCode+"'";
            }
            //将增强后的sql放回
            statementHandler.setValue("delegate.boundSql.sql",sql);
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object o) {
        //生成代理对象
        return Plugin.wrap(o, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
